import java.io.*;
import java.net.InetAddress;
import java.net.ServerSocket;
import java.net.Socket;
import java.net.SocketTimeoutException;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;

public class TCPServer {

    private static final int PORT = 9000;
    private static final int TIMEOUT = 60000;   // 超时设置（单位：毫秒）
    public static void main(String[] args) {
        try {
            fileServer();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public static void fileServer() throws Exception {
        // 创建线程池，优化并发连接处理
        ExecutorService executorService = Executors.newFixedThreadPool(10);

        // 创建服务端Socket
        try (ServerSocket serverSocket = new ServerSocket(PORT)) {
            serverSocket.setSoTimeout(TIMEOUT); // 设置超时等待

            System.out.println("等待客户端连接...");

        // 不断接收客户端连接
            while (true) {
                try {
                    Socket socket = serverSocket.accept();
                    // 如果客户端连接成功，交由线程池处理
                    executorService.submit(() -> handleClient(socket));

                } catch (SocketTimeoutException e) {
                    System.out.println("等待超时，没有客户端连接，服务已关闭.");
                    break; // 退出等待循环，关闭服务
                } catch (IOException e) {
                    System.err.println("服务端发生异常: " + e.getMessage());
                    e.printStackTrace();
                }
            }
        } catch (IOException e) {
            System.err.println("ServerSocket 初始化失败: " + e.getMessage());
            e.printStackTrace();
        }
    }

    private static void handleClient(Socket socket) {
        try {
            InetAddress clientAddress = socket.getInetAddress();
            System.out.println("连接的客户端IP为: " + clientAddress);

            // 获取输入流接收文件
            InputStream is = socket.getInputStream();
            DataInputStream dataInputStream = new DataInputStream(is);

            // 读取文件名
            String fileName = dataInputStream.readUTF();
            FileOutputStream fos = new FileOutputStream(new File(fileName));
            byte[] buffer = new byte[1024];
            int len;
            int totalBytesReceived = 0;

            // 接收文件内容并写入
            while ((len = dataInputStream.read(buffer)) != -1) {
                fos.write(buffer, 0, len);
                totalBytesReceived += len;
            }
            System.out.println("服务端接收文件 " + fileName + " 成功，接收了 " + totalBytesReceived + " 字节");

            // 通知客户端文件接收成功
            OutputStream os = socket.getOutputStream();
            os.write(("文件接收成功: " + fileName).getBytes());

            // 关闭流
            fos.close();
            dataInputStream.close();
            socket.close();
        } catch (IOException e) {
            System.err.println("客户端处理出错: " + e.getMessage());
            e.printStackTrace();
        }
    }
}
